const http = require('http');
const context = require('./context');
const request = require('./request');
const response = require('./response');


class Koa {

    constructor(){
        this.middwares = [];
    }

    listen(...args){
        
        const server = http.createServer(async (req,res)=>{

            const ctx = this.createContext(req,res);
            
            const fn = this.compose(this.middwares);
            
            await fn(ctx);

            res.end(ctx.body);
        });

        

        server.listen(...args);
    }

    createContext(req,res){
        const ctx = Object.create(context);

        ctx.request = Object.create(request);
        ctx.response = Object.create(response);

        ctx.req = ctx.request.req = req;
        ctx.res = ctx.response.res = res;

        return ctx;


    }

    compose(mids){

        return function(ctx){
            
            return dispatch(0);
    
            function dispatch(i){
                let fn = mids[i];
                if(!fn){
                    return Promise.resolve();
                }
    
                return Promise.resolve(fn(ctx,function next(){
                    return dispatch(i + 1);
                }))
            }
        }
    }

    use(mid){
        this.middwares.push(mid);
    }




}


module.exports = Koa;